📄 decode.s
字号:
;
; Module: decode - MPEG-I audio decoding subroutines
;
; Initial version: R. Huang 2/21/97
; Jinshi Huang 12/1/98 for LS388/LS500
;
; Call : r27 ; set up return address for called subroutine,
; seek_sync, decode_info
; I_decode_bitalloc, I_decode_scale,
; I_CRC_calc, I_buffer_sample,
; I_dequantize_sample, I_denormalize_sample,
; II_decode_bitalloc, II_decode_scale,
; II_CRC_calc, II_buffer_sample,
; II_dequantize_sample, II_denormalize_sample,
; recover_CRC_error
; Return : r26 ; return to caller, musicout
; Permanent:
; Temp reg:
; AGR reg:
; Local buffer:
.nolist
; global include file
#include "regdef.h"
#include "common.h"
#include "memory.h"
#include "mpg_mac.h"
#include "user.h"
; local include file
; test reference file, to be removed
#define FRAMECOUNT 1
.list
.text
.globl SUB_seek_sync_mpg
.globl SUB_decode_info
.globl SUB_I_decode_bitalloc
.globl SUB_I_decode_scale
.globl SUB_I_CRC_calc
.globl SUB_I_buffer_sample
.globl SUB_II_decode_bitalloc
.globl SUB_II_decode_scale
.globl SUB_II_CRC_calc
.globl SUB_II_buffer_sample
.globl SUB_chk_CRC
.globl SUB_recover_CRC_error
.set noreorder
// input: r11, always a multiple of 8, seeking intger of bytes
/* Seeking SYNC_WORD_MPG */
SUB_seek_sync_mpg:
dlw r10,Stream_Wr_Ptr
dlw r8,Stream_Rd_Ptr
shr r14,r11,3 // bit to byte
tst r10,r8
bgte check_ss_space0
addi r10,IBUF_SIZE
check_ss_space0:
sub r10,r8
tst r10,r14
bgt ss_space_ok0
movi r10,F_SYNC_ERROR
j seek_sync_done
ss_space_ok0:
dlw r10,Stream_Wr_Ptr
mov r8,Gb_Getbits_Ptr
shl r8,5
shr r8,8
tst r10,r8
bgte check_ss_space
addi r10,IBUF_SIZE
check_ss_space:
sub r10,r8
tst r10,r14
bgt ss_space_ok
movi r10,F_SYNC_ERROR
j seek_sync_done
ss_space_ok:
dlw r8,0xe024 // dumi, but can not be omitted, strange ??!!
mov r8,Gb_Getbits_Ptr
andi r8,0x7
tsti r8,0
beq 2f
rsubi r8,0x8 //r8 = remaining bits
nop
gb r10,r8 // byte-align
//ignoring prefix sub r11,r8 // r11: bits to be seeked
nop
2:
gbi r8,0xc // get 12 bits
subi r11,0xc
tsti r8,SYNC_WORD_MPG // qualify SYNC_WORD_MPG
beq seek_4_more_bits
reseek_sync1:
#if NEW_SS // new seek sync scheme
gbi r10,4 // get 4 more bits
subi r11,4
shl r8,4
or r8,r10 // pack 3 bytes
andi r8,0xfff // mask
tsti r8,SYNC_WORD_MPG // qualify SYNC_WORD_MPG
beq seek_4_more_bits
#else // NEW_SS
gbi r10,1 // get one more bit
subi r11,1
shl r8,1
or r8,r10 // pack 3 bytes
andi r8,0xfff // mask
tsti r8,SYNC_WORD_MPG // qualify SYNC_WORD_MPG
beq seek_4_more_bits
tsti r10,0
bne reseek_sync1
#endif // NEW_SS
movi r10,F_SYNC_ERROR
tsti r11,32 // 32: prevent sign alternation.
bgt reseek_sync1
j seek_sync_done
seek_4_more_bits:
gbi r14,4 // get 4 more bit
subi r11,4 // sub # of bits
nop
tsti r14,0xf // in return, r14 has first 4 bits of info
beq seek_4_more_bits
#if 0
andi r0,r11,0x7 // check byte alignment
#else
andi r0,r11,0x3 // check nibble alignment
/* RH 11-04-99: Sync words in some SVCDs align to nibble instead of byte. */
#endif
tsti r0,0
bne reseek_sync1 // reseek if not aligned
movh r0,LIstatus
andi r0,NO_SYNC_ERROR
movi r10,0
movh LIstatus,r0
seek_sync_done:
j r26
/* Decoding header (covers 'decode_info' and 'hdr_to_frps' in C code) */
// input: r14=first 4 bits of info (from seek_sync)
SUB_decode_info:
/* decode_info */
// gbi r8,1
andi r8,r14,0x8 //bit 3
shr r8,3
nop
tsti r8,0
beq decode_info_done_error // 0: illegal version
movb LBhdr_version,r8
// gbi r8,2
andi r8,r14,0x6
shr r8,1 //bit2-1
movi r9,4
sub r9,r8
// gbi r8,1
andi r8,r14,0x1 //bit0
movb LBhdr_lay,r9 // save layer number, not original parameter
movb LBhdr_error_protection,r8
gbi r8,4
nop
tsti r8,0
beq decode_info_done_error // 0: illegal bitrate_index
tsti r8,0xf
beq decode_info_done_error // f: illegal bitrate_index
movb LBhdr_bitrate_index,r8
gbi r8,2
nop
movi r11,4
tsti r8,2 // 0: 44.1kHz, 1: 48kHz
bgte decode_info_done_error // 2: 32kHz, 3: reserved
movb LBhdr_sampling_frequency,r8
#ifdef QT_SYNC //-------------------------
movb r9,LBhdr_lay
tsti r9,0x2
bne skip_frmsize_lookup
movb r9,LBhdr_bitrate_index
tsti r8,0x0
bne chk_48kHz
#if ISO
#ifndef MPEG_2
movi r8,ITfrmsizeII441_offset
shl r9,1 // bitrate_index * 2 (offset for half data)
add r9,r8
dlhr r8,r9
nop
nop
movh LIfrmsize_offset,r8
#endif // MPEG_2
#else // ISO
movi r8,ITfrmsizeII441_offset
shl r9,1 // bitrate_index * 2 (offset for half data)
add r9,r8
dlhr r8,r9
nop
nop
movh LIfrmsize_offset,r8
#endif // ISO
movi r8,ITfrmsizeII441
j frmsize_lookup
chk_48kHz:
tsti r8,0x1
bne chk_32kHz
movi r8,ITfrmsizeII480
j frmsize_lookup
chk_32kHz:
movi r8,ITfrmsizeII320
frmsize_lookup:
movb r9,LBhdr_bitrate_index
shl r9,1 // bitrate_index * 2 (offset for half data)
add r9,r8
dlhr r8,r9
nop
nop
movh LIfrmsize,r8
skip_frmsize_lookup:
#endif // QT_SYNC
gbi r8,1
nop
movb LBhdr_padding,r8
gbi r8,1
nop
movb LBhdr_extension,r8
gbi r9,2
nop
movb LBhdr_mode,r9
gbi r8,2
nop
movb LBhdr_mode_ext,r8
gbi r8,1
nop
movb LBhdr_copyright,r8
gbi r8,1
nop
movb LBhdr_original,r8
gbi r8,2
nop
movb LBhdr_emphasis,r8
/* hdr_to_frps */
movi r8,1
tsti r9,MPG_MD_MONO
beq htf_005
movi r8,2
htf_005:
movb LBfr_ps_stereo,r8
movi r8,SBLIMIT
movb r9,LBhdr_lay
tsti r9,2
bne htf_010
/* pick_table */
subi r9,1
multi r9,15 // 15 entries for each layer in index table
nop
movb r8,LBhdr_bitrate_index
add r8,r9
shl r8,1 // offset for half data
addi r8,ITbitrate
dlhr r9,r8
movb r8,LBfr_ps_stereo
subi r8,1
shrv r9,r8 // r9 = br_per_ch
// = bitrate[lay][bsp]/fr_ps->stereo
movb r8,LBhdr_sampling_frequency
tsti r9,56
blt ck_tab1 // branch if br_per_ch < 56
tsti r8,1
beq pk_tab0 // branch if sfrq = 48
tsti r9,80
bgt ck_tab1 // branch if br_per_ch > 80
pk_tab0:
movi r9,0 // ( sfreq==48 && br_per_ch>=56 ) ||
// ( br_per_ch>=56 && br_per_ch<=80 )
movi r8,27 // sblimit for table 0
j pt_010
ck_tab1:
tsti r8,1
beq ck_tab2 // branch if sfrq = 48
tsti r9,96
blt ck_tab2 // branch if br_per_ch < 96
movi r9,1 // ( sfrq!=48 && br_per_ch>=96 )
movi r8,30 // sblimit for table 1
j pt_010
ck_tab2:
tsti r8,2
beq pk_tab3 // branch if sfrq = 32
tsti r9,48
bgt pk_tab3 // branch if br_per_ch > 48
movi r9,2 // ( sfrq!=32 && br_per_ch<=48 )
movi r8,8 // sblimit for table 2
j pt_010
pk_tab3:
movi r9,3
movi r8,12 // sblimit for table 3
pt_010:
movb LBfr_ps_sblimit,r8
movb LBtable,r9
/* load alloc table */
tsti r9,2
bgte pt_012
LdAddr r2,I2Aalloc_0_1
shr r2,2
SetDma 31 // (31+1) words, total 55 words
movi LocalAddr,local_I2Aalloc_0_1_word
// local buffer address in word
dmarr r2
WaitDma
addi r2,32
SetDma 22 // (22+1) words, total 55 words
movi LocalAddr,local_I2Aalloc_0_1_word+32
// local buffer address in word
dmarr r2
WaitDma
LdAddr r2,ITaloc_idx_0_1
shr r2,2
SetDma 7 // (7+1) words
movi LocalAddr,local_ITaloc_idx_word // local buffer address in word
dmarr r2
WaitDma
j htf_010
pt_012:
LdAddr r2,I2Aalloc_2_3
shr r2,2
SetDma 29 // (29+1) words
movi LocalAddr,local_I2Aalloc_2_3_word
// local buffer address in word
dmarr r2
WaitDma
movi AGRAdr5,local_B2Aquant2
movi AGRAdr6,local_B2Aquant
CLR_TrapReg
loop 6,pt_align_quant
mov r2,a5(4)
mov a6(4),r2
pt_align_quant:
movi AGRAdr5,local_B2Agroup2
movi AGRAdr6,local_B2Agroup
loop 6,pt_align_group
mov r2,a5(4)
mov a6(4),r2
pt_align_group:
movi AGRAdr5,local_B2Abits2
movi AGRAdr6,local_B2Abits
loop 6,pt_align_bits
mov r2,a5(4)
mov a6(4),r2
pt_align_bits:
SET_TrapReg
LdAddr r2,ITaloc_idx_2_3
shr r2,2
SetDma 2 // (2+1) words
movi LocalAddr,local_ITaloc_idx_word
// local buffer address in word
dmarr r2
WaitDma
htf_010:
movb r9,LBhdr_lay
tsti r9,1
bne not_loading_nb_table
;-----------read FAnb_table. This should be done when layer_I is decided
movi BlockSkip,0
movi BlockSize, 27 ;get 28 words
movi DMASize, 27
la r1, (FAnb_table) ;external memory addr in bytes
shr r1, 2 ;make a word addr
movi r3, local_FAnb_table_word
mov LocalAddr, r3
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -