; ; This program originally available on the Motorola DSP bulletin board. ; It is provided under a DISCLAMER OF WARRANTY available from ; Motorola DSP Operation, 6501 Wm. Cannon Drive W., Austin, Tx., 78735. ; ;************************************************************************** ; ; ADPCMNS.ASM Full-Duplex 32-kbit/s Nonstandard CCITT ADPCM ; ; Version 1.0 - 8/9/90 ; ; This program implements the algorithm defined in CCITT Recommendation ; G.721: "32 kbit/s Adaptive Differential Pulse Code Modulation" dated ; August 1986. This code contains a real-time I/O interface for a ; hardware platform consisting of two DSP56000ADS boards, each connected ; to an MC145503 codec. ; ; Please refer to the file ADPCMNS.HLP for further information about ; this program. Also refer to Motorola Application Report APR9/D for ; complete documentation. ; ;************************************************************************** OPT CC,CEX START EQU $0020 PBDDR EQU $FFE2 PBD EQU $FFE4 PCC EQU $FFE1 CRA EQU $FFEC CRB EQU $FFED SSISR EQU $FFEE SSIRX EQU $FFEF SSITX EQU $FFEF BCR EQU $FFFE ORG X:$0000 ;******************** Encoder variables *********************************** ; I = siii 0000 | 0000 0000 | 0000 0000 (ADPCM format) I_T DS 1 ;ADPCM codeword ; DQ = siii iiii | iiii iii.f | ffff ffff (24SM) DQ_T DS 1 ;Quantized difference signal ; Y = 0iii i.fff | ffff ffff | ffff ffff (23SM) Y_T DS 1 ;Quantizer scale factor ; AP = 0ii.f ffff | ffff ffff | ffff ffff (23SM) AP_T DS 1 ;Unlimited speed control parameter ; AL = 0i.ff ffff | ffff ffff | ffff ffff (23SM) AL_T DS 1 ;Limited speed control parameter ;******************** Decoder variables *********************************** I_R DS 1 ;ADPCM codeword DQ_R DS 1 ;Quantized difference signal Y_R DS 1 ;Quantizer scale factor AP_R DS 1 ;Unlimited speed control parameter AL_R DS 1 ;Limited speed control parameter ;******************** Temporary variables ********************************* ; IMAG = 0000 0000 | 0000 0000 | 0000 0iii. IMAG DS 1 ;|I| ; PKS1 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) PKS1 DS 1 ;XOR of PK0 & PK1 ; PKS2 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) PKS2 DS 1 ;XOR of PK0 & PK2 DATAPTR_T DS 1 ;Transmit data buffer pointer DATAPTR_R DS 1 ;Receive data buffer pointer ;******************** Table for quantizing DLN **************************** ; Used in QUAN routine QUANTAB DS 8 ;******************** Table for unquantizing I **************************** ; Used in RECONST IQUANTAB DS 8 ;******************** W(I) lookup table *********************************** ; Used in FUNCTW routine WIBASE DS 8 ;******************** F(I) lookup table *********************************** ; Used in FUNCTF routine FIBASE DS 8 ;******************** Table used in COMPRESS ****************************** TAB DS 8 ;******************** Encoder data buffer ********************************* ; DQ = siii iiii | iiii iiii. | ffff ffff (24TC) ; SRn in same format DATA_T DSM 8 ;8 word modulo buffer for data, ; R2 is used as pointer, DATAPTR_T ; points to start of buffer (DQ1) ; at beginning of cycle ;******************** Decoder data buffer ********************************* DATA_R DSM 8 ;8 word modulo buffer for data ; (same format as DATA_T) ORG Y:$0000 ;******************** Encoder variables *********************************** ; SE = siii iiii | iiii iiii. | ffff ffff (24TC) SE_T DS 1 ;Signal estimate ; SEZ = siii iiii | iiii iiii. | ffff ffff (24TC) SEZ_T DS 1 ;Partial signal estimate ; SR = siii iiii | iiii iiii. | ffff ffff (24TC) SR_T DS 1 ;Reconstructed signal ; PK0 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) PK0_T DS 1 ;Sign of DQ + SEZ ; PK1 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) PK1_T DS 1 ;Delayed sign of DQ + SEZ ; DMS = 0iii. ffff | ffff ffff | ffff ffff (23SM) DMS_T DS 1 ;Short term average of F(I) ; DML = 0iii. ffff | ffff ffff | ffff ffff (23SM) DML_T DS 1 ;Long term average of F(I) ; TDP = i000 0000 | 0000 0000 | 0000 0000 (1TC) TDP_T DS 1 ;Tone detect ; TD = i000 0000 | 0000 0000 | 0000 0000 (1TC) TD_T DS 1 ;Delayed tone detect ; YU = 0iii i.fff | ffff ffff | ffff ffff (23SM) YU_T DS 1 ;Fast quantizer scale factor ; YL = 0iii i.fff | ffff ffff | ffff ffff (23SM) YL_T DS 1 ;Slow quantizer scale factor ; SIGPK = i000 0000 | 0000 0000 | 0000 0000 (1TC) SIGPK_T DS 1 ;Sgn[p(k)] flag ; A2P = si.ff ffff | ffff ffff | ffff ffff (24TC) A2P_T DS 1 ;Second order predictor coef ; TR = i000 0000 | 0000 0000 | 0000 0000 (1TC) TR_T DS 1 ;Transition detect ; S = psss qqqq | 0000 0000 | 0000 0000 (PCM log format) S_T DS 1 ;Input PCM signal ;******************** Decoder variables *********************************** SE_R DS 1 ;Signal estimate SEZ_R DS 1 ;Partial signal estimate SR_R DS 1 ;Reconstructed signal PK0_R DS 1 ;Sign of DQ + SEZ PK1_R DS 1 ;Delayed sign of DQ + SEZ DMS_R DS 1 ;Short term average of F(I) DML_R DS 1 ;Long term average of F(I) TDP_R DS 1 ;Tone detect TD_R DS 1 ;Delayed tone detect YU_R DS 1 ;Fast quantizer scale factor YL_R DS 1 ;Slow quantizer scale factor SIGPK_R DS 1 ;Sgn[p(k)] flag A2P_R DS 1 ;Second order predictor coef TR_R DS 1 ;Transition detect SP_R DS 1 ;Output PCM signal ;******************** Temporary variables ********************************* DQMAG DS 1 ;|DQ| SL_T DS 1 ;PCM input for encoder LAW DS 1 ;PCM mode select ;******************** Shift constant lookup table ************************* ; Shift constants used for doing left or right shifts by multiplying by a ; power of 2. RSHFT DS 24 LSHFT ;******************** Encoder coef. buffer ******************************** ; Bn = si.ff ffff | ffff ffff | ffff ffff (24TC) ; An in same format ;8 word modulo buffer for coefs., ; R6 is used as pointer COEF_T DSM 8 ;B1 ;B2 ;B3 ;B4 ;B5 ;B6 ;A1 ;A2 ;******************** Decoder coef. buffer ******************************** ;8 locations for coef. queue ; (same format as COEF_T) COEF_R DSM 8 ;B1 ;B2 ;B3 ;B4 ;B5 ;B6 ;A1 ;A2 PAGE ORG P:$0000 JMP START ORG P:START MOVEC #$06,OMR ;Set DE=1 CLR A MOVEP A,X:BCR ;Set BCR for 0 wait states JSR INIT ;************************************************************************** ; ; Poll SSI for receiver data available. Note that the SSI transmit and ; receive are synchronous. ; ;************************************************************************** IOWAIT JCLR #7,X:SSISR,IOWAIT ;Wait for SSIRX full MOVE Y:SP_R,A ;Get decoder output MOVEP A,X:SSITX ;Send PCM output to CODEC MOVEP X:SSIRX,A ;Get input sample MOVE A,Y:S_T ;Save PCM input for encoder ;************************************************************************** ; ; Encoder ; ;************************************************************************** ENCODE MOVE X:DATAPTR_T,R2 ;Set data pointer to DQ1EXP MOVE #COEF_T,R6 ;Set coef pointer to B1 JSR 1 ; = AP(k-1) if AP(k-1) <= 1 ; ; Inputs: ; AP = 0ii.f ffff | ffff ffff | ffff ffff (23SM) ; ; Outputs: ; AL = 0i.ff ffff | ffff ffff | ffff ffff (23SM) ; ;************************************************************************** LIMAMIX MOVE #<$20,X0 ;Get '1' CMP X0,A ;Test AP TGT X0,A ;If AP>'1' set AL='1' ASL A ;Shift to align radix pt. ;************************************************************************** ; MIX ; ; Form linear combination of fast and slow quantizer ; scale factors ; ; Y(k) = AL(k) * YU(k-1) + [1 - AL(k)] * YL(k-1) ; ; Inputs: ; YL = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; AL = 0i.ff ffff | ffff ffff | ffff ffff (23SM) ; YU = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ; Outputs: ; Y = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ;************************************************************************** TFR Y0,A A,X1 ;Swap YU and AL SUB Y1,A ;Find YU-YL ABS A A,B ;Find |YU-YL|, save sign MOVE A,Y0 MPY X1,Y0,A ;Find PRODM=|YU-YL|*AL NEG A A,X0 ;Find -PRODM, save PRODM TST B Y1,B ;Check sign TPL X0,A ;If sign=0 PROD=PRODM, ; else PROD=-PRODM ADDL B,A ;Find Y=PROD+YL RTS ;************************************************************************** ; EXPAND ; ; Convert A-law or mu-law PCM to uniform PCM (according to ; Recommendation G.711). For further details see Motorola ; application bulletin "Logarithmic/Linear Conversion ; Routines for DSP56000/1". ; ; Input: ; S = psss qqqq | 0000 0000 | 0000 0000 (PCM log format) ; ; Output: ; SL = siii iiii | iiii ii.00 | 0000 0000 (14TC) ; ;************************************************************************** CONVERT MOVE A,X0 #>$80,Y1 ;Get shift constant MPY X0,Y1,A #>$7F,X1 ;Shift S to 8 lsb's of A1 AND X1,A ;Mask off sign of S MOVE A1,N3 ;Load |S| as offset CMPM Y1,A ;Check sign of S MOVE X:(R3+N3),A ;Lookup |SL| from ROM table JGE >3 & combine with EXP ;************************************************************************** ; SUBTB ; ; Scale log version of difference signal by subtracting ; scale factor ; ; DLN(k) = DL(k) - Y(k) ; ; Inputs: ; DL = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; Y = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ; Output: ; DLN = siii i.fff | ffff ffff | ffff ffff (24TC) ; ;************************************************************************** SUBTB SUB Y0,A ;Find DLN=DL-Y ;************************************************************************** ; QUAN ; ; Quantize difference signal in log domain ; ; log2|D(k)| - Y(k) | |I(k)| ; ------------------+-------- ; [3.12, + inf) | 7 ; [2.72, 3.12) | 6 ; [2.34, 2.72) | 5 ; [1.91, 2.34) | 4 ; [1.38, 1.91) | 3 ; [0.62, 1.38) | 2 ; [-0.98, 0.62) | 1 ; (- inf, -0.98) | 0 ; ; Inputs: ; DLN = siii i.fff | ffff ffff | ffff ffff (24TC) ; DS = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) ; ; Output: ; I = siii 0000 | 0000 0000 | 0000 0000 (ADPCM format) ; ;************************************************************************** MOVE #QUANTAB,R0 ;Get quantization table base MOVE #>QUANTAB+2,X1 ;Get offset for quan conversion MOVE X:(R0)+,X0 ;Get quan table value TSTDLN CMP X0,A X:(R0)+,X0 ;Compare to DLN JGE >20 MOVE A1,N0 ;Load IMAG as offset into IQUAN table MOVE A1,X:IMAG ;Save |I| MOVE X:(R0+N0),A ;Lookup DQLN ;************************************************************************** ; ADDA ; ; Add scale factor to log version of quantized difference ; signal ; ; DQL(k) = DQLN(k) + Y(k) ; ; Inputs: ; Y = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; DQLN = siii i.fff | ffff 0000 | 0000 0000 (12TC) ; ; Output: ; DQL = siii i.fff | ffff ffff | ffff ffff (24TC) ; ;************************************************************************** ADD B,A ;Find DQL=DQLN+Y ;************************************************************************** ; ANTILOG ; ; Convert quantized difference signal from log to linear ; domain. Use approximation 2**(x) = 1 + x ; ; Input: ; DQL = siii i.fff | ffff ffff | ffff ffff (24TC) ; DQS = sXXX 0000 | 0000 0000 | 0000 0000 (1TC) ; ; Outputs: ; DQ = siii iiii | iiii iii.f | ffff ffff (24SM) ; ;************************************************************************** JPL =0 convert DQL, ; else DQL<0, set |DQ|=0 TFR Y1,A #<$80,X0 ;Get DQS (MSB of I), get mask AND X0,A #0,B ;Mask off DQS, set |DQ|=0 MOVE B1,Y:DQMAG ;Save DQMAG=|DQ| JMP $0A,X0 ;Shift DEX>>19, get '10' SUB X0,B #$7FFFFF,X0 ;Find DQT shift=DEX-10 JEQ 24 x 2**(YL(k)) ; 0 otherwise ; ; Inputs: ; TD = i000 0000 | 0000 0000 | 0000 0000 (1TC) ; YL = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; DQ = siii iiii | iiii iii.f | ffff ffff (24SM) ; ; Output: ; TR = i000 0000 | 0000 0000 | 0000 0000 (1TC) ; ;************************************************************************** TRANS TST A #0,A ;Check TD, set TR=0 JEQ >10), get '1' OR X0,A B,X1 ;Add implied '1' to YLFRAC, MOVE Y:RSHFT+19,Y1 ;Get shift const MPY Y1,X1,B #>$08,X0 ;Find YLINT=YL>>19, get '8' MOVE B1,B ;Clear fractional portion CMP X0,B #>$05,X0 ;Compare YLINT to '8', get '5' JGT 8 set maximum THR2 SUB X0,B ;Find YLINT-5 JEQ DQTHR leave TR=1, ; else DQMAG<=DQTHR, set TR=0 SAVETR RTS ;************************************************************************** ; ADDB ; ; Add quantized difference signal and signal estimate ; to form reconstructed signal ; ; SR(k-n) = SE(k-n) + DQ(k-n) ; ; Inputs: ; DQ = siii iiii | iiii iii.f | ffff ffff (24SM) ; SE = siii iiii | iiii iiii. | ffff ffff (24TC) ; ; Output: ; SR = siii iiii | iiii iiii. | ffff ffff (24TC) ; ;************************************************************************** ADDBC TST A Y:DQMAG,A ;Check DQS, get DQMAG JPL >8) ADD Y1,A ;Find BnP=Bn+UBn MOVE A1,Y:(R6)+ ;Store BnP to Bn ENDUPB RTS ;************************************************************************** ; UPA2 ; ; Update the A2 coefficient of the second order predictor. ; ; A2(k) = [1-(2**-7)] * A2(k-1) ; + (2**-7) * { sgn[P(k)] * sgn[P(k-2)] ; - F[A1(k-1)] * sgn[P(k)] * sgn[P(k-1)] } ; ; F[A1(k)] = 4 * A1 if |A1|<=(2**-1) ; = 2 * sgn(A1) if |A1|>(2**-1) ; ; Inputs: ; A1 = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC) ; A2 = Y:(R6+1) = si.ff ffff | ffff ffff | ffff ffff (24TC) ; SIGPK = i000 0000 | 0000 0000 | 0000 0000 (1TC) ; PK0 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) ; PK1 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) ; PK2 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) ; (Note: PKS1 & PKS2 have been previously calculated) ; ; Outputs: ; A2T = si.ff ffff | ffff ffff | ffff ffff (24TC) ; ;************************************************************************** UPA2 MOVE X:PKS2,A ;Get PKS2=PK0**PK2 MOVE #<$10,Y0 ;Get '+1' TST A #<$F0,Y1 ;Check PKS2, get '-1' TPL Y0,A ;If PKS2=0, set UGA2A='+1' TMI Y1,A ;If PKS2=1, set UGA2A='-1' MOVE A,X1 Y:(R6)+,A ;Save UGA2A, get A1 MOVE #$1FFF00,Y0 ;Get '+1.99' CMP Y0,A #$E00100,Y1 ;Check A1, get '-1.99' TGT Y0,A ;If A1>=1/2, set FA1='1.99' CMP Y1,A X:PKS1,B ;Check A1 again, get PKS1=PK0**PK1 TLT Y1,A ;If A1<=-1/2, set FA1='-1.99' TST B ;Check PKS1 JMI >7 TST B Y:(R6),Y0 ;Check SIGPK, get A2 TMI X0,A ;If SIGPK=1, set UGA2=0 MOVE Y:RSHFT+7,X0 ;Get shift constant MAC -Y0,X0,A ;Find UA2=UGA2-(A2>>7) ADD Y0,A ;Find A2T=A2+UA2 ;************************************************************************** ; LIMC ; ; Limit the A2 coefficient of the second order predictor. ; ; |A2(k)| <= '0.75' ; ; Inputs: ; A2T = si.ff ffff | ffff ffff | ffff ffff (24TC) ; ; Outputs: ; A2P = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC) ; ;************************************************************************** MOVE #<$D0,X0 ;Get A2LL CMP X0,A #<$30,X1 ;Check A2P, get A2UL TLT X0,A ;If A2P<-0.75, set A2P=-0.75 CMP X1,A ;Check A2P again TGT X1,A ;If A2P>0.75, set A2P=0.75 RTS ;************************************************************************** ; UPA1 ; ; Update the A1 coefficient of the second order predictor. ; ; A1(k) = [1-(2**-8)] * A1(k-1) ; + 3 * (2**-8) * sgn[P(k)] * sgn[P(k-1)] ; ; Inputs: ; A1 = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC) ; SIGPK = Y:(R0) = i000 0000 | 0000 0000 | 0000 0000 (1TC) ; PK0 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) ; PK1 = sXXX XXXX | XXXX XXXX | XXXX XXXX (1TC) ; (Note: PKS1 has been previously calculated) ; ; Outputs: ; A1T = si.ff ffff | ffff ffff | ffff ffff (24TC) ; ;************************************************************************** UPA1 MOVE #$00C000,Y0 ;Get +gain MOVE X:PKS1,B ;Get PKS1=PK0**PK1 TST B #$FF4000,Y1 ;Check PKS1, get -gain TPL Y0,A ;If PKS=0, set UGA1=+gain TMI Y1,A ;If PKS=1, set UGA1=-gain MOVE X1,B TST B #0,X1 ;Check SIGPK TMI X1,A ;If SIGPK=1, set UGA1=0 MOVE Y:(R6),X1 ;Get A1 MOVE Y:RSHFT+8,Y0 ;Get shift constant MAC -Y0,X1,A ;Find UA1=UGA1-(A1>>8) ADD X1,A ;Find A1T=A1+UA1 ;************************************************************************** ; LIMD ; ; Limit the A1 coefficient of the second order predictor. ; ; |A1(k)| <= [1-(2**-4)] - A2(k) ; ; Inputs: ; A1T = si.ff ffff | ffff ffff | ffff ffff (24TC) ; A2P = si.ff ffff | ffff ffff | ffff ffff (24TC) ; ; Outputs: ; A1P = Y:(R6) = si.ff ffff | ffff ffff | ffff ffff (24TC) ; ;************************************************************************** MOVE #<$3C,B ;Get OME='1-(2**-4)' SUB X0,B ;Find A1UL=OME-A2P CMP B,A B,X0 ;Check A1T TGT X0,A ;If A1T>A1UL, set A1P=A1UL NEG B #2,N6 ;Find A1LL=-A1UL=A2P-OME CMP B,A B,X0 ;Check A1T again TLT X0,A ;If A1T>5)+DMS ;************************************************************************** ; FILTB ; ; Update long term average of F(I) ; ; DML(k) = (1 - 2**(-7)) * DML(k-1) + 2**(-7) * F[I(k)] ; ; Inputs: ; FI = 0iii. 0000 | 0000 0000 | 0000 0000 (3SM) ; DML = 0iii. ffff | ffff ffff | ffff ffff (23SM) ; ; Output: ; DMLP = 0iii. ffff | ffff ffff | ffff ffff (23SM) ; ;************************************************************************** SUB Y1,B Y:RSHFT+7,X1 ;Find DIF=FI-DML TFR Y1,B B,X0 MAC X0,X1,B ;Find DMLP=(DIF>>7)+DML RTS ;************************************************************************** ; SUBTC ; ; Compute magnitude of the difference of short and long ; term functions of quantizer output sequence and then ; perform threshold comparison for quantizing speed control ; parameter. ; ; AX = 1 if Y(k)>=3, TD(k)=1, & |DMS(k)-DML(k)|>(2**-3)*DML(k) ; = 0 otherwise ; ; Input: ; Y = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; DMSP = 0iii. ffff | ffff ffff | ffff ffff (23SM) ; DMLP = 0iii. ffff | ffff ffff | ffff ffff (23SM) ; TDP = i000 0000 | 0000 0000 | 0000 0000 (1TC) ; ; Output: ; AX = 0i0.0 0000 | 0000 0000 | 0000 0000 (1SM) ; ;************************************************************************** SUBTC SUB B,A Y:RSHFT+3,X0 ;Find DIF=DMSP-DMLP ABS A B,Y0 ;Find DIFM=|DIF| MPY X0,Y0,B #<$40,X0 ;Find DTHR=DMLP>>3, get '1' CMP B,A #0,B ;Compare DIFM & DTHR, set AX=0 TGE X0,B ;If DIFM>=DTHR set AX=1 MOVE X1,A ;Get TDP TST A #<$18,Y0 ;Check TDP, get '3' TNE X0,B ;If TDP!=0 set AX=1 MOVE Y1,A CMP Y0,A ;Check for Y<"3" TLT X0,B ;If Y<"3" set AX=1 RTS ;************************************************************************** ; FILTC ; ; Low pass filter of speed control parameter ; ; AP(k) = (1-2**(-4)) * AP(k-1) + AX ; ; Inputs: ; AX = 0i0.0 0000 | 0000 0000 | 0000 0000 (1SM) ; AP = 0ii.f ffff | ffff ffff | ffff ffff (23SM) ; ; Outputs: ; APP = 0ii.f ffff | ffff ffff | ffff ffff (23SM) ; ;************************************************************************** FILTC SUB X1,B Y:RSHFT+4,Y0 ;Find DIF=AX-AP TFR X1,A B,X0 MAC X0,Y0,A ;Find APP=(DIF>>4)+AP ;************************************************************************** ; TRIGA ; ; Speed control trigger block ; ; AP(k) = AP(k) if TR(k)=0 ; = 1 if TR(k)=1 ; ; Inputs: ; TR = i000 0000 | 0000 0000 | 0000 0000 (1TC) ; APP = 0ii.f ffff | ffff ffff | ffff ffff (23SM) ; ; Outputs: ; APR = 0ii.f ffff | ffff ffff | ffff ffff (23SM) ; ;************************************************************************** MOVE Y1,B TST B #<$20,X0 ;Check TR, get '1' TMI X0,A ;If TR=1 set APR=1, else APR=APP RTS ;************************************************************************** ; FUNCTW ; ; Map quantizer output into logarithmic version of scale ; factor multiplier ; ; |I(k)| | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; ---------+-----+-----+-----+-----+-----+-----+-----+-----+ ; W(I) |70.13|22.19|12.38| 7.00| 4.00| 2.56| 1.13|-0.75| ; ; Inputs: ; I = siii. 0000 | 0000 0000 | 0000 0000 ; ; Outputs: ; WI = siii iiii. | ffff 0000 | 0000 0000 (12TC) ; ;************************************************************************** FUNCTW MOVE #WIBASE,R0 ;Load lookup table base MOVE X:IMAG,N0 ;Load IMAG as offset NOP MOVE X:(R0+N0),A ;Get WI from lookup table ;************************************************************************** ; FILTD ; ; Update of fast quantizer scale factor ; ; YU(k) = (1 - 2**(-5)) * Y(k) + 2**(-5) * W[I(k)] ; ; Inputs: ; WI = siii iiii. | ffff 0000 | 0000 0000 (12TC) ; Y = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ; Outputs: ; YUT = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ;************************************************************************** MOVE Y:RSHFT+3,X1 ;Get shift constant MAC -Y0,X1,A Y0,B ;Find DIF=WI-(Y>>3) ASR A ADDR B,A ;Find YUT=(DIF>>5)+Y (actually DIF>>2) ;************************************************************************** ; LIMB ; ; Limit quantizer scale factor ; ; 1.06 <= YU(k) <= 10.00 ; ; Inputs: ; YUT = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ; Outputs: ; YUP = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ;************************************************************************** MOVE #<$50,X0 ;Get upper limit '10' CMP X0,A #$088000,X1 ;Check for YU>10, ; get lower limit '1.06' TGT X0,A ;If YU>10 set YU=10 CMP X1,A ;Check for YU<1.06 TLT X1,A ;If YU<1.06 set YU=1.06 MOVE A,X0 ;Save YUP ;************************************************************************** ; FILTE ; ; Update of slow quantizer scale factor ; ; YL(k) = (1 - 2**(-6)) * YL(k-1) + 2**(-6) * YU(k) ; ; Inputs: ; YUP = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; YL = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ; Outputs: ; YLP = 0iii i.fff | ffff ffff | ffff ffff (23SM) ; ;************************************************************************** MOVE Y1,B SUB B,A Y:RSHFT+6,Y0 ;Find DIF=YUP-YL TFR B,A A,X1 MAC Y0,X1,A ;Find YLP=(DIFSX>>6)+YL RTS ;************************************************************************** ; COMPRESS ; ; Convert from uniform PCM to A-law or mu-law PCM (according to ; Recommendation G.711). For further details see Motorola ; application bulletin "Logarithmic/Linear Conversion ; Routines for DSP56000/1". ; ; Input: ; SR = siii iiii | iiii iiii. | 0000 0000 (16TC) ; ; Output: ; SP = psss qqqq | 0000 0000 | 0000 0000 (PCM log format) ; ;************************************************************************** COMPRESS MOVE #$002100,Y0 ;Get bias TST B X1,A JNE >1 <<23 DC $200000 ;>>2 <<22 DC $100000 ;>>3 <<21 DC $080000 ;>>4 <<20 DC $040000 ;>>5 <<19 DC $020000 ;>>6 <<18 DC $010000 ;>>7 <<17 DC $008000 ;>>8 <<16 DC $004000 ;>>9 <<15 DC $002000 ;>>10 <<14 DC $001000 ;>>11 <<13 DC $000800 ;>>12 <<12 DC $000400 ;>>13 <<11 DC $000200 ;>>14 <<10 DC $000100 ;>>15 <<9 DC $000080 ;>>16 <<8 DC $000040 ;>>17 <<7 DC $000020 ;>>18 <<6 DC $000010 ;>>19 <<5 DC $000008 ;>>20 <<4 DC $000004 ;>>21 <<3 DC $000002 ;>>22 <<2 DC $000001 ;>>23 <<1