📄 pcm_pcm.s
字号:
ori r3, 0xffff //default unity gain
tsti r2, 15
blt Lgross_gain
addi r1, 1
Lgross_gain:
subi r1, 4
tsti r1, 0
blte Lno_gain //do only attenuation for now
shrv r3, r1 //adjust gain value
Lno_gain:
movw r2, LWpcmscale //gain from user
mulf r4, r2, r3 //compound gain
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
dlw r0,MUTE_BLK_CNT
nop
tsti r0,40
bgte Lapply_gain_to_samples
addi r0,1
dsw r0,MUTE_BLK_CNT
movi r4,0
Lapply_gain_to_samples:
dlh r1, DiskAttrib
nop
tsti r1, 1 // test if a DTS CD
beq noPCMQSound // bypass volume control and QExpander
movi r0, 0xffff //lower 16-bit mask
mupi r1, 0xffff //upper 16-bit mask
movi AGRAdr0, local_FApcm_buf_byte
movi TrapReg,0
nop
nop
#ifdef I2S
loop 24, Lpcm_gain_outer
loop 32, Lpcm_gain_inner
shl r3, a0(0*4), 16 //get 16-bit sample
shra r3, 8 //sign-extented to 1.23 format
mulf r6, r4, r3
nop
rnd r6
nop
nop
nop
shl a0(1*4), r6, 7 //align to MSB with 1 right shift
Lpcm_gain_inner:
Lpcm_gain_outer:
#else // I2S
#ifdef EFFECT
loop 8, Lpcm_gain_outer
#else //EFFECT
loop 24, Lpcm_gain_outer
#endif //EFFECT
loop 32, Lpcm_gain_inner
and r3, r1, a0(0*4) //get upper 16-bit
shra r3, 8 //sign-extented to 1.23 format
mulf r6, r4, r3
and r3, r0, a0(0*4) //get lower 16-bit// pipeline
rnd r6
shl r3, 16
shra r3, 8 //sign-extented to 1.23 format
mulf r8, r4, r3
shl r6, 8 //align to upper 16-bit// pipeline
rnd r8
and r6, r1 //keep only 16-bit data
nop
nop //pipeline
shr r8, 8 //align to lower 16-bit
and r8, r0 //keep only 16-bit data
// shl r8,16
// shr r6,16
or a0(1*4), r6, r8 //put back 32-bit pair
Lpcm_gain_inner:
Lpcm_gain_outer:
#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
noPCMQSound:
#endif // MSW_ADD_QSOUND
#endif // I2S
//====================================================
// Arrange Data and DMA Starts Here
//====================================================
movi BlockSkip, 4
movi BlockSize, 1 // block size = 2
movi StartAddrHigh, DataSeg //to second segment
movi AGRSiz0, 0xffff
movi AGRSiz1, 0xffff
dlh r1, DiskAttrib
nop
tsti r1, 1 // test if a DTS CD
bne non_DTS_section
/////// DTS Data Alignment, Cross Swap and shift 16 bits
/////// DTS Data Alignment, Shift 16 bits
movi AGRAdr0, local_FApcm_buf_byte + 0x400- 4
movi AGRAdr1, SP_draft_before_dram_byte - 4
dlw r4, DTS_left_over
shl r1, a0(0*4), 8 // Low Half
shr r2, a0(-1*4), 16 // High Half
shl r2, 8
mov a1(-1*4), r1
dsw r2, DTS_left_over
loop 255, align_DTS_data
shl r1, a0(0*4), 8 // Low Half
shr r2, a0(-1*4), 16 // High Half
shl r2, 8
mov a1(-1*4), r2
mov a1(-1*4), r1
align_DTS_data:
mov a1(-1*4), r4 // Store left 16-bit
j spdif_raw_data
non_DTS_section:
//====================================================
// PCM Data Arrange and DMA starts here
//====================================================
movi AGRAdr0, local_FApcm_buf_byte + 0x400- 4
movi AGRAdr1, SP_draft_before_dram_byte - 4
rlwi r1, PCM_Out_Ctrl
andi r1, 0x0080
tsti r1, 0
bne 3f
// For non-I2S Right justify
loop 256, pcm_right_justify
mov r1, a0(0*4) // Low Half
shr r2, a0(-1*4),16 // High Half
mov a1(-1*4), r2
mov a1(-1*4), r1
pcm_right_justify:
j pcm_center_justify
3:
// For I2S Center justify
loop 256, pcm_center_justify
shl r1, a0(0*4), 8 // Low Half
shr r2, a0(-1*4), 8 // High Half
mov a1(-1*4), r2
mov a1(-1*4), r1
pcm_center_justify:
movi r3, local_FApcm_buf_word // (word addr) 0x400 = (byte addr) 0x1000
shr r9, r10, 2 // to word addr
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:
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
#if ENABLE_PSM
nop
nop
nop
jsr r25,disp_spectrum
nop
#endif
//---------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------
//====================================================
// SPDIF Data Arrange and DMA starts here
//====================================================
movi AGRAdr0, SP_draft_before_dram_byte - 4
rlwi r1, PCM_Out_Ctrl
andi r1, 0x0080
tsti r1, 0
beq SPDIF_center_justify
movi AGRAdr2, local_FApcm_buf_byte
loop 256, spdif_swap_for_I2S
mov r1, a2(1*4) // Low Half
mov r2, a2(-1*4) // High Half
mov a2(1*4), r2
mov a2(1*4), r1
spdif_swap_for_I2S:
j spdif_raw_data
// For non-I2S SPDIF center justify
SPDIF_center_justify:
loop 256, spdif_raw_data
shl r1, a0(-1*4), 8
shl r2, a0(1*4), 8
mov a0(-1*4), r2
mov a0(-1*4), r1
spdif_raw_data:
movi r3, local_FApcm_buf_word // (word addr) 0x400 = (byte addr) 0x1000
shr r9, r10, 2 // to word addr
addi r9, 4
loop 16, merge_pcm_spdif // total of 256*2 words
mov LocalAddr, r3
dmawr r9
WaitDma
addi r3, 32 //32 words each block
addi r9, 16 * 6 //32*3
merge_pcm_spdif:
//========== End of DMA =============
movi TrapReg,1<<2
movi BlockSkip, 0
movi BlockSize, 0
movi StartAddrHigh,MEM_SEG
// Make sure PCMOUT is enabled. This is only necessary for the
// first time.
dlw r0,MUTE_FLAG
movi r1,0x31
tsti r0,1
beq Lalready_on
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
pcm_not_out:
#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 + -