📄 arith_encoder_jpeg2000.asm
字号:
/*****************************************************************************
Prototype :void arith_enc_renorme(struct * enc_reg);
In renormalization function both interval reg. A and code reg. C are shifted,
one bit at a time. The number of shift is counted by register CT. When CT
becomes zero ,a compressed data is copied to output buffer by calling function
arith_enc_byteout. Renormalization is done until A is no longer less than
0x8000.
Registers Used : R0-R2, P0, P5.
*******************************************************************************/
.section program;
.global __arith_enc_renorme;
.align 8;
__arith_enc_renorme:
P0 = R0; // Address of structure mq_enc
[--SP] = P5; // push P5
P5 = R0;
R0 = [P0++]; // fetch interval reg. A
R1 = [P0++]; // fetch code reg. C
R2 = [P0] ; // fetch counter reg. CT
DECREMENT:
R0 <<=1; // shift both A and C reg by 1 bit
R1 <<=1;
R2 += -1; // decrement CT
CC=R2==0; // check if CT==0
IF CC JUMP GET_BYTE_1; // if true call byteout else check if A<0x8000
TEST_0X8000:
CC = BITTST(R0,15); // check if A & 0x8000==1
IF !CC JUMP DECREMENT; // if false jump to decrement
[P5++] = R0;
[P5++] = R1;
[P5++] = R2; // store A,C,CT
P5 = [SP++];
RTS;
GET_BYTE_1:
[P0--] = R2;
[P0--] = R1;
[P0--] = R0; // store A,C ,CT
R0 = P5;
[--SP] = RETS;
CALL __arith_enc_byteout;
// call byteout to store byte to output buffer
RETS = [SP++];
R0 = [P5];
R1 = [P5+4]; // get updated A,C,CT
R2 = [P5+8];
JUMP TEST_0X8000;
__arith_enc_renorme.end:
/*****************************************************************************
Prototype : void arith_enc_byteout(struct * enc_reg);
This routine contains bit-stuffing procedures which are needed to limit carry
propagation into the completed bytes of compressed data. B register holds the
compressed data. If B == 0xFF , bit stuffing is done ,otherwise carry bit is
checked. If carry bit is set it is added to B and again checked if B==0xff to
see if a bit stuffing is needed. After need for bit stuffing has determined, B
value is stored and new value of B is derived from C register and CT register is
set accordingly.
Registers Used : R0-R3, R7, P0, P2.
*******************************************************************************/
.section program;
.global __arith_enc_byteout;
.align 8;
__arith_enc_byteout:
P0 = R0; // Address of structure mq_enc
[--SP] = R7;
R3 = 255; // Initialize to compare with 255
R0 = [P0+4]; // fetch value of Code register C
R7 = R1-R1(NS) || R1 = [P0+12];
// fetch value of compressed data B
R2 = [P0+16]; // get value of first byte
P2 = [P0+20]; // address of output buffer
CC = R1 == R3; // check if B = 0xff
IF CC JUMP BIT_STUFF; // if true do bit stuffing
R7.H = 0X800;
CC = R0<R7; // check if carry bit is set in C
IF CC JUMP NO_BIT_STUFF;// if true no bit stuffing required
R1+= 1; // Add carry to B register
CC = R1==R3; // compare B register with 0xff
IF !CC JUMP NO_BIT_STUFF;
BITCLR(R0,27); // clear carry bit
BIT_STUFF:
CC = R2 == 0; // check if first_byte flag==0
IF CC JUMP CP_OUTPUT;
R2 = 0; // clear first_byte flag
JUMP GET_NEXT_B;
CP_OUTPUT:
B[P2++] = R1; // store B register to output buffer
GET_NEXT_B:
R1 = R0 >> 20 || [P0+20] = P2;
// get next B from C register and store output
// buffer address
R7.L = -1;
R7.H = 0XF;
R0 = R0&R7;
R7 = 7; // initialize count register CT to 7
[P0+16] = R2; // store first_byte flag
[P0+12] = R1; // store B register
[P0+8] = R7; // store CT register
[P0+4] = R0; // store C register
R7 = [SP++];
RTS;
NO_BIT_STUFF:
CC = R2==0; // check if first_byte flag is set
IF CC JUMP CP_OUTPUT1;
R2 = 0; // clear first_byte
JUMP GET_NEXT_B1;
CP_OUTPUT1:
B[P2++] = R1; // store B register to output buffer
GET_NEXT_B1:
R1 = R0 >> 19; //Change from 535 to 533
[P0+20] = P2;
// get next B value from C register and store output
// buff address
R7.L = -1;
R7.H = 7;
R0 = R0&R7;
R7 = 8;
[P0+16] = R2; // store fist_byte flag
[P0+12] = R1; // store B register
[P0+8] = R7; // store CT register
[P0+4] = R0; // store C register
R7 = [SP++];
RTS;
__arith_enc_byteout.end:
/******************************************************************************
Prototype : void arith_enc_flush(struct * enc_reg);
This procedure is used to terminate the encoding operation and generate the
required terminating marker. This procedure guarantees that 0xff prefix to the
marker code overlaps the final bits of compressed data. This routine sets as may
bits in the C register to 1 as possible. The exclusive upper bound for the C reg
is sum of C register and interval register A. The low order 16 bits of C are
forced to 1, and the result is compared to upper bound. If C reg is too big
leading 1 bit is removed, reducing C to a value is within the interval. If the
Byte B is 0xff then it is discarded, otherwise stored to output buffer.
Registers Used : R0-R3, R7, P0, P2, P5.
*****************************************************************************/
.section program;
.global __arith_enc_flush;
.align 8;
__arith_enc_flush:
P0 = R0; // address of structure mq_enc
[--SP] = (R7:7,P5:5);
P5 = R0;
R2 = R1-R1(NS) || R0 = [P0++];
// clear R2 and fetch interval register A
R7 = R1-R1(NS) || R1 = [P0++];
// clear R7 and fetch code register C
R2.L = -1;
R7.L = 0X8000;
R0 = R1+R0(NS) || R3 = [P0--];
// temp=C + A, fetch CT
R1 = R1|R2; // set as many lower bits of C to 1
CC = R0<=R1; // check if TEMP<=C
R0 = 0;
IF CC R0 = R7;
R1 = R1-R0; // if C register is too big remove leading bit
R1 = LSHIFT R1 BY R3.L; // shift C by CT
[P0] = R1; // store value of C
R0 = P5;
[--SP] = RETS;
CALL __arith_enc_byteout;
// call byteout to store compressed data
R1 = [P5+4]; // get updated C
R2 = [P5+8]; // fetch value of CT
R1 = LSHIFT R1 BY R2.L; // shift left C value by CT
[P5+4] = R1; // store C register
R0 = P5;
CALL __arith_enc_byteout;
// call byteout to store the compressed data
R0 = [P5+12]; // fetch B value
P2 = [P5+20]; // Address of output buffer to store last byte
R2 = 255;
RETS = [SP++];
(R7:7,P5:5) = [SP++];
CC = R0==R2; // check if B==0xff5
IF !CC JUMP WRITE_BYTE; // if true discard the value
RTS;
WRITE_BYTE:
B[P2++] = R0; // else store the last byte
RTS;
__arith_enc_flush.end:
/******************************************************************************
Prototype: void arith_init(struct mq_enc*,unsigned char *);
In this routine A,C,CT,B registers are initialized. Interval register A is
initialized to 0x8000. Code register C and Byte register B are set to zero.
Count register is set to 12.First_byte flag is set to one.
Registers Used : R0-R3, P0.
*******************************************************************************/
.section program;
.global __arith_enc_init;
.align 8;
__arith_enc_init:
P0 = R0; // Address of structure mq_enc
R2.L = 0x8000;
R2.H = 0;
R3 = 12;
R0 = R1-R1(NS) || [P0++] = R2;
// Initialize A to 0X8000
[P0++] = R0; // Initialize C reg. to 0
[P0++] = R3; // Initialize CT register to 12
[P0++] = R0; // Initialize B register to 0
R0 = 1;
[P0++] = R0; // set first_byte flag to 1
[P0++] = R1; // store address of output buffer address
RTS;
NOP;
__arith_enc_init.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -