📄 arith_decoder_mpeg4.asm
字号:
__arith_decoder_mpeg4:
P0 = R1; // Address of structure decoder
[--SP] = (R7:5); // Push R7:5
R2 = R0-R0(NS)||R6 = [P0];
// fetch value of lower range register
BITSET(R2,16); // set r2 = 0x8000
R2 = R2-R0(NS)||R7 = [P0+4];
// R0 = probability of '0'.R2 = probability of'1'
// and get Range value
R5 = R7>>16; // Higher 16 bits of range register
CC = R2<R0; // check if probability of '0' is greater then
// probability of '1'
IF CC R0 = R2; // probability of LPS (CLPS)
R3 = CC; // R3 == Least probable symbol
R5 = R5.L*R0.L(FU); // Range LPS(rLPS) == R * CLPS
R7 = R7-R5(NS); // Range == Range -range of LPS
R2 = R6+R7(NS); // Lower value += Range -range of LPS
R0 = R3<<0||R1 = [P0+8];// fetch decoder->V register
R1 = R1-R6(NS); // decoder->V - decoder->L
BITTGL(R0,0); // opposite of LPS
CC = R7 <= R1(IU); // check if (decoder->R-rLPS) < =
// (decoder->V-decoder->L)
IF CC R7 = R5; // if true Range == range of LPS
IF !CC R3 = R0;
IF !CC R2 = R6; // if false lower range == previous lower range
[P0+4] = R7; // store Range value in decoder->R register
R7 = R3<<0||[P0] = R2; // store decoder->L register
[--SP] = RETS; // Push RETS register before calling a function
R0 = P0; // argument to function decode_renormlise
CALL __decode_renormlise;
RETS = [SP++]; // Pop RETS register
R0 = R7;
(R7:5) = [SP++]; // Pop R7:5
RTS;
NOP;
__arith_decoder_mpeg4.end:
/*******************************************************************************
Prototype : void decode_renormlise(Arcoder *decoder);
As long as decoder->R is smaller than QUATER(0x40000000), renormalization is
performed.
If the interval(L,L+R) is within [0,HALF], the interval is scaled to [2L,2(L+R)]
and V is scald to 2V. If the interval(L,L+R) is within [HALF,1], the interval is
scaled to [2(L-HALF),2(L-HALF+R)] and V is scald to 2(V-HALF). Otherwise the
interval is scaled to 2(L-QUATER),2(L-QUATER+R) and V is scaled to 2(V-QUATER).
After each scaling, a bit is read and copied into the least significant bit of
register decoder->V.
Registers used : R0-R3, R6, R7, P0-P2, P5.
*******************************************************************************/
.section program;
.global __decode_renormlise;
.align 8;
__decode_renormlise:
P0 = R0; // Address of structure decoder
[--SP] = (R7:6); // Push R7:6,P5
[--SP] = P5;
[--SP] = RETS;
P5 = R0; // Duplicate the address of coder
R7 = R1-R1(NS)||R0 = [P0];
// fetch coder->L
R6 = R0-R0(NS)||R1 = [P0+4];
// fetch coder->R
BITSET(R7,31); // set r7 == 0x80000000
BITSET(R6,30); // set r6 == 0x40000000
CHK_WHILE:
CC = R1<R6(IU);
// check if code->R <0x40000000
IF !CC JUMP NORME_END; // if false jump to NORME_END
CC = R7 <= R0(IU); // check if coder->L >0x80000000
IF !CC JUMP CHK_ELSE_IF;
R0 = R0-R7(NS)||R1 = [P0+8];
// coder->L -= 0x80000000
R1 = R1-R7(NS)||[P0] = R0;
// store coder->L value
[P0+8] = R1; // decoder->V -= HALF
JUMP END_WHILE;
CHK_ELSE_IF:
R2 = R0+R1; // Add decoder->L and decoder->R
CC = R2 <= R7(IU); // check if coder->L+coder->R < = 0x80000000
IF CC JUMP END_WHILE;
R0 = R0-R6(NS)||R1 = [P0+8];
// decrement coder->L by 0x40000000
R1 = R1-R6(NS)||[P0] = R0;
// store modified coder->L value
[P0+8] = R1; // decoder->V -= QUATER
END_WHILE:
R0 = [P0];
R0 = R0<<1||R1 = [P0+4];// double coder->L
R1 = R1<<1||[P0] = R0; // double coder->R
[P0+4] = R1; // and store updated values
R0 = P5;
CALL __AddNextInputBit; // get next bit and copy to LSB of
// decoder->V register
R0 = [P5];
R1 = [P5+4]; // fetch updated value of decoder->L ,R registers
JUMP CHK_WHILE; // repeat the procedure till coder->R < 0x40000000
NORME_END:
RETS = [SP++];
P5 = [SP++];
(R7:6) = [SP++]; // POP RETS and R7:6,P5 register
RTS;
NOP;
__decode_renormlise.end:
/******************************************************************************
Prototype : void AddNextInputBit(ArDecoder *decoder);
In this procedure any stuffed bits are removed. One bit is read from input array
and copied to LSB of V register.
Registers used : R0-R3, P0-P2.
*******************************************************************************/
.section program;
.global __AddNextInputBit;
.align 8;
__AddNextInputBit:
P0 = R0; // address of structure decoder
R1 = 1;
R3 = [P0+12]; // fetch decoder->arpipe
R2 = R3>>30||P1 = [P0+52];
// fetch address of input array
CC = BITTST(R2,0); // check input bit == 1
IF CC JUMP ELSE_CONDITION;
R2 = [P0+24];
R2 += -1;
[P0+24] = R2; // decrement decoder->nzeors by 1
CC = R2 == 0;
IF !CC JUMP COND_OVER;
R0 = [P0+36]; // fetch decoder->extrabits
R0 = R0-R1(NS)||R2 = B[P1++](Z);
// flush a stuffed bit
[P0+36] = R0; // store decoder->extrabits += -1
ELSE_CONDITION:
R2 = [P0+44]; // fetch decoder->mm
[P0+28] = R1; // store decoder->nonzero
[P0+24] = R2; // store decoder->nzerof = decoder->mm
COND_OVER:
R0 = 31;
R3 = R3<<1||R1 = [P0+36];
R0 = R0+R1(NS)||R2 = B[P1++](Z);
// flush a bit
P2 = R0; // offset to fetch current bit
R2 = [P0+8]; // fetch decoder->V
R2 = R2<<1; // shift left decoder->nzerof by 1 and fetch nzerof
R0 = 1;
P2 = P2+P1;
R1 = B[P2](Z); // fetch a bit
R1 = R1&R0;
R2 = R2+R1(NS)||R0 = [P0+32];
// add bit to LSB of decoder->V
R3 = R3+R1(NS)||[P0+8] = R2;
// add bit to LSB of decoder->arpipe
CC = R1 == 0;
IF !CC JUMP NO_DECREMENT;
R0 += -1;
[P0+32] = R0; // decrement decoder->nzerof
CC = R0 == 0;
IF !CC JUMP OVER;
R0 = [P0+36];
R0 += 1;
[P0+36] = R0;
NO_DECREMENT:
R0 = [P0+44]; // fetch decoder->mm
[P0+32] = R0; // store decoder-> nzerof as decoder->mm
OVER:
[P0+12] = R3; // store decoder-> arpipe
[P0+52] = P1; // store the current pointer of input array
RTS;
NOP;
__AddNextInputBit.end:
/*******************************************************************************
Prototype : void StopArDecoder( ArDecoder *decoder);
After the last symbol has been decoded,additional bits need to be consumed which
are introduced by the encoder for proper decodability. In general 3 further bits
need to be read. However in some cases, only 2 bits need to be read. These cases
are defined by
i) if the current interval covers entirely[QUATER-1,HALF]
ii) if the current interval covers entirely [ HALF-1, 3*QUATER].
Registers used : R0-R3, R5-R7, P0-P2, P5.
*******************************************************************************/
.section program;
.global __StopArDecoder;
.align 8;
__StopArDecoder:
P0 = R0; // Address of decoder
[--SP] = (R7:5,P5:5); // Push R7:5,P5 and RETS register
P5 = R0; // store the address in P5
R0 = [P0]; // get value of coder->L
R3 = 8;
R7 = R0>>29||R2 = [P0+4];
// fetch value of coder->R
R6 = R0+R2;
R6 = R6>>29;
CC = R6 == 0;
IF CC R6 = R3;
R6 = R6-R7;
CC = R6 == 3;
R2 = CC;
CC = BITTST(R7,0); // conditional check to find how many bits to read
R1 = CC;
[--SP] = RETS;
R0 = P5;
R7 = R2&R1;
CALL __AddNextInputBit; // fetch next bits and copy to LSB of
// decoder->V reg.
CC = R6 <= 3;
IF !CC JUMP CALL_END;
CC = R7 == 1;
IF CC JUMP CALL_END;
R0 = P5;
CALL __AddNextInputBit; // fetch next bits and copy to LSB of
// decoder->V reg.
CALL_END:
R0 = [P5+28];
CC = R0 == 0; // check if nzeros == 0
IF CC JUMP FLUSH_BITPLUS;
// if true flush a bit
R1 = [P5+44];
R2 = [P5+48]; // get difference of decoder->mm-decoder->mt
R1 = R1-R2(NS)||R0 = [P5+24];
CC = R0<R1;
IF !CC JUMP NO_CALL;
FLUSH_BITPLUS:
P1 = [P5+52];
R0 = B[P1++](Z);
[P5+52] = P1; // flush the final bit
NO_CALL:
RETS = [SP++];
(R7:5,P5:5) = [SP++];
RTS;
NOP; //to avoid one stall if LINK or UNLINK happens to be
//the next instruction after RTS in the memory.
__StopArDecoder.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -