📄 jpegencoder2.asm
字号:
;JpegEncoder2.asm
.ARMS_off ;enable assembler for ARMS=0
;告诉编译器当前工作状态为DSP模式
.CPL_on ;enable assembler for CPL=1
;告诉编译器当前工作在SP直接寻址模式(SP与DP对应)
.mmregs
.include "MyDspDef.inc"
.ref _Rbuf,_Gbuf,_Bbuf
.ref _YDU,_CbDU,_CrDU
.ref _ColorConvMatrix
.asg XAR1,pRbuf;指向R缓冲区的指针
.asg AR1,pRbufShort;指向R缓冲区的指针
.asg XAR2,pGbuf;指向G缓冲区的指针
.asg AR2,pGbufShort;指向G缓冲区的指针
.asg XAR3,pBbuf;指向B缓冲区的指针
.asg AR3,pBbufShort;指向B缓冲区的指针
.asg XAR4,pYUVbuf;指向YUV缓冲区的指针
.asg AR4,pYUVbufShort;指向YUV缓冲区的指针
.asg XAR5,pConvMatrix;指向ColorConvMatrix缓冲区的指针
.asg AR5,pConvMatrixShort;指向ColorConvMatrix缓冲区的指针
.asg BSA45, db_base;循环缓冲区的起始地址
.asg BK47, db_sz;循环缓冲区的大小
ST2mask .set 0000000000100000b ;circular/linear pointers,打开ar5的循环寻址模式
.global _RGB2YUV,CalcOneComponent
_RGB2YUV:
pshboth(XAR1)
pshboth(XAR2)
pshboth(XAR3)
pshboth(XAR4)
pshboth(XAR5)
@(ST0_55) &= #01FFh || mmap();清零ACOVx, TC1, TC2, C
@(ST1_55) |= #04140h || mmap();将CPL(SP直接寻址模式), SXMD, FRCT设置为1
@(ST1_55) &= #0F9DFh || mmap();清零M40, SATD(饱和标志), 54CM
@(ST2_55) &= #07A00h || mmap();清零ARMS, RDM(不懂), CDPLC, AR[0-7]LC
@(ST3_55) &= #0FFDDh || mmap();清零SATA(会影响目的存储器,正向饱和与负向饱和), SMUL
@(ST2_55) |= #ST2mask || mmap();设置circular/linear ARx
nop
nop
nop
pConvMatrixShort = #(-0x80);//暂时借用一下
hi(ac1) = pConvMatrixShort
;ac1 += #0;0x4000
pYUVbuf = #_YDU
pConvMatrix = #_ColorConvMatrix
db_base = #_ColorConvMatrix;计算Y分量
db_sz = #3
pConvMatrixShort = #0;索引变成0
call CalcOneComponent
pYUVbufShort = #_CbDU;注意Y、Cr、Cb缓冲应该放在一起,一个页内
db_base = #(_ColorConvMatrix+3);计算Cb分量
ac1 = #0;0x4000;
call CalcOneComponent
pYUVbufShort = #_CrDU
db_base = #(_ColorConvMatrix+6);计算Cr分量
ac1 = #0;0x4000;
call CalcOneComponent
;保存C函数运行需要的环境
bit(ST2, K_FRCT) = #0;清FRCT
@(ST2_55) &= #0FE00h || mmap();清 CDPLC(关闭循环寻址) 和 AR[7-0]LC
bit(ST2, K_ARMS) = #1;设置 ARMS = #1 ,恢复为控制模式
bit(ST1,K_FRCT) = #0
XAR5 = popboth()
XAR4 = popboth()
XAR3 = popboth()
XAR2 = popboth()
XAR1 = popboth()
return
CalcOneComponent:
pRbuf = #_Rbuf
pGbuf = #_Gbuf
pBbuf = #_Bbuf
brc0 = #63;循环64次
localrepeat{
ac0 = (*pRbufShort+) * (*pConvMatrixShort+)
ac0 += ((*pGbufShort+) * (*pConvMatrixShort+))
ac0 += ((*pBbufShort+) * (*pConvMatrixShort+))
ac0 = rnd(ac0);4舍5入
ac0 += ac1
(*pYUVbufShort+) = hi(ac0);
}
return
.asg XAR0,pInputBuf;指向Input缓冲区的指针
.asg AR0,pInputBufShort;指向Input缓冲区的指针
.asg XAR3,pOutputBuf;指向Output缓冲区的指针
.asg AR3,pOutputBufShort;指向Output缓冲区的指针
.asg XAR2,pQtableBuf;指向_Q_table缓冲区的指针
.asg AR2,pQtableBufShort;指向_Q_table缓冲区的指针
.asg XAR1,pZigzagBuf;指向zigzag缓冲区的指针
.asg AR1,pZigzagBufShort;指向zigzag缓冲区的指针
.global _DctBlockQuantize
_DctBlockQuantize:
push(t0,t1)
bit(ST1,#K_FRCT) = #1
nop
nop
nop
brc0 = #63;循环64次
; pshboth(XAR1);pInputBuf = #_imageBlock ; XAR4 = popboth()
; pshboth(XAR2);pOutputBuf = #_YDCTzigzagQ ; XAR3 = popboth()
; pshboth(XAR3);pQtableBuf = #_Q_table ; XAR2 = popboth()
; pshboth(XAR4);pZigzagBuf = #_zigzag ; XAR1 = popboth()
localrepeat{
t0 = *pZigzagBufShort+
t1 = *pQtableBufShort(t0)
ac0 = rnd(t1 * *pInputBufShort+)
*pOutputBufShort(t0) = hi(ac0);
}
bit(ST1,#K_FRCT) = #0
t0,t1 = pop()
return
.global _ClearStReg
_ClearStReg:
nop
nop
@(ST0_55) = #0x1047 || mmap()
@(ST1_55) = #0x6900 || mmap()
@(ST2_55) = #0xf000 || mmap()
@(ST3_55) = #0x1c86 || mmap()
nop
nop
nop
nop
nop
return
.ref _ImageWidth
.asg XAR0,pSourceBuf;指向Source缓冲区的指针
.asg AR0,pSourceBufShort;指向Source缓冲区的指针
.asg XAR1,pDistBuf;指向Dist缓冲区的指针
.asg AR1,pDistBufShort;指向Dist缓冲区的指针
.global _Mem8x8Cpy
_Mem8x8Cpy:
push(t0)
t0 = *(#_ImageWidth)
t0 -= #7
brc0 = #7;外循环8次
csr = #6;内循环7次
localrepeat{
repeat(csr)
*pDistBufShort+ = *pSourceBufShort+
*pDistBufShort+ = *(pSourceBufShort+t0);
}
t0 = pop()
return
; .global _jpe1
; .asg XAR0,i
; .asg AR0,i
;_jpe1:
; i = #63;
; return
.global _ACEncode2
.asg XAR0,pDCTzigzagQ
.asg AR0,pDCTzigzagQShort
.asg XAR1,p_ac_encode_tab
.asg AR1,p_ac_encode_tabShort
.asg AR7,tmp
.asg AR6,tmp1
.asg t0,i
;.bss m_bAllAcZero_asm,1
.bss nrzeroes,1
.bss endpos,1
.bss startpos,1
.bss m_bK_Y_AC,1
.bss Tmpi,1
.bss EncodeAc,1
.ref _AddBits
K_Y_AC .set 0
K_CbCr_AC .set 1
_ACEncode2:
*(m_bK_Y_AC) = t0;保护K_Y_AC/K_CbCr_AC
t0 = #63
ZERO_Detect_NOT_finish:
tmp1 = *pDCTzigzagQShort(t0);从右到左
if(tmp1 != #0)goto ZERO_Detect_finish_t0_gt_0;t0大于0的情况
if(t0 == #0)goto ZERO_Detect_finish_t0_eq_0;等于0的情况
t0 -= #1 || goto ZERO_Detect_NOT_finish
ZERO_Detect_finish_t0_eq_0:
;*(m_bAllAcZero_asm) = #1;等于0的情况
tmp = *(m_bK_Y_AC)
*(endpos) = t0
if(tmp != #K_Y_AC)goto ZERO_Detect_finish_t0_eq_0_CbCr_AC
t1 = #4
t0 = #10
pshboth(XAR1)
pshboth(XAR2)
call _AddBits;是K_Y_AC的情况
XAR2 = popboth()
XAR1 = popboth()
goto AC_ENCODE_END
ZERO_Detect_finish_t0_eq_0_CbCr_AC:
pshboth(XAR1)
pshboth(XAR2)
t1 = #2
t0 = #0
call _AddBits;是K_CbCr_AC的情况
XAR2 = popboth()
XAR1 = popboth()
goto AC_ENCODE_END
ZERO_Detect_finish_t0_gt_0:
;*(m_bAllAcZero_asm) = #0;t0大于0的情况
*(endpos) = t0;
i = #1
i_lt_or_equ_endpos:
tmp = *(endpos) - i
if(tmp < #0)goto i_gt_endpos ;while (i <= endpos)
*(startpos) = i
begin_to_dectect_nrzeroes:
tmp = *(endpos) - i
if(tmp <= #0)goto nrzeroes_detect_finish
tmp = *pDCTzigzagQShort(i)
if(tmp != 0)goto nrzeroes_detect_finish
i += #1 || goto begin_to_dectect_nrzeroes
nrzeroes_detect_finish:
tmp = i - *(startpos);//连零的数量
tmp1 = #16
AC_LESS_OR_MORE_THAN_16:
tc1 = uns(tmp < tmp1) || nop ;如果连零的数量小于16
if(tc1)goto nrzeroes_lt_16;连零数量小于16
*(Tmpi) = i ;保护i的值
tmp -= #16
*(nrzeroes) = tmp
tmp = *(m_bK_Y_AC)
if(tmp != #K_Y_AC)goto CbCr_AC_MORE_THAN_16_ZEROS
Y_AC_MORE_THAN_16_ZEROS:
t1 = #11
t0 = #2041
pshboth(XAR1)
pshboth(XAR2)
call _AddBits
XAR2 = popboth()
XAR1 = popboth()
i = *(Tmpi);恢复i
goto AC_LESS_OR_MORE_THAN_16;继续判断连零数量是否小于16
CbCr_AC_MORE_THAN_16_ZEROS:
t1 = #10
t0 = #1018
pshboth(XAR1)
pshboth(XAR2)
call _AddBits
XAR2 = popboth()
XAR1 = popboth()
i = *(Tmpi);恢复i
goto AC_LESS_OR_MORE_THAN_16;继续判断连零数量是否小于16
nrzeroes_lt_16:;连零数量小于16
ac1 = tmp || t3 = #10
ac1 = t3 * ac1
t1 = #0;AC编码的长度
ac0 = *pDCTzigzagQShort(i)
ac0 = |ac0|
EncodeAcCalStart:
if(ac0 == #0)goto EncodeAcCalFinish
ac0 = ac0>>1 || t1 += #1
goto EncodeAcCalStart
EncodeAcCalFinish:
*(EncodeAc) = t1
ac1 += t1;在AcMapStrTab中的位置
ac1 -= #1
*(Tmpi) = i ;保护i的值
i = LO(ac1)
t0 = *p_ac_encode_tabShort(i)
i += #160
t1 = *p_ac_encode_tabShort(i)
pshboth(XAR1)
pshboth(XAR2)
call _AddBits
XAR2 = popboth()
XAR1 = popboth()
i = *(Tmpi);恢复i
tmp = *pDCTzigzagQShort(i)
if(tmp >= #0)goto InputBlock_i_gt_or_equ_0
tmp1 = *(EncodeAc)
tmp1 -= #16
if(tmp1 < 0)goto EncodeAc_lt_16
EncodeAc_equ_16:
;tmp = *pDCTzigzagQShort(i)
ac0 = |tmp|
ac0 ^= #0xffff
t0 = lo(ac0)
t1 = *(EncodeAc)
goto Ac_inv_finish
EncodeAc_lt_16:
t1 = *(EncodeAc)
ac0 = #0xffff
ac0 = ac0 <<< t1
ac0 = ~ac0
;tmp = *pDCTzigzagQShort(i)
ac1 = |tmp|
ac0 ^= ac1
t0 = lo(ac0)
Ac_inv_finish:
goto InputBlock_i_fix_finish
InputBlock_i_gt_or_equ_0:
t0 = *p_ac_encode_tabShort(i)
t1 = *(EncodeAc)
InputBlock_i_fix_finish:
pshboth(XAR1)
pshboth(XAR2)
call _AddBits
XAR2 = popboth()
XAR1 = popboth()
i = *(Tmpi);恢复i
i += #1
goto i_lt_or_equ_endpos
i_gt_endpos:
ac0 = *(endpos)
ac0 -= #63
if(ac0 >= 0)goto AC_ENCODE_END
tmp = *(m_bK_Y_AC)
if(tmp != #K_Y_AC)goto CbCr_AC_MORE_THAN_16_ZEROS2
t1 = #11
t0 = #2041
pshboth(XAR1)
pshboth(XAR2)
call _AddBits
XAR2 = popboth()
XAR1 = popboth()
i = *(Tmpi);恢复i
goto AC_ENCODE_END;
CbCr_AC_MORE_THAN_16_ZEROS2:
t1 = #10
t0 = #1018
pshboth(XAR1)
pshboth(XAR2)
call _AddBits
XAR2 = popboth()
XAR1 = popboth()
i = *(Tmpi);恢复i
AC_ENCODE_END:
return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -